# 穿心解卡控制器

from fastapi import APIRouter
from common.method import *
from pydantic import BaseModel
# from common.params import PiercParams
import math

router = APIRouter()


class ReqSoftParams(BaseModel):
    # 套管内径D
    casing_inner_diameter: float
    # 工具外径d
    tool_outer_diameter: float
    # 曲率半径R
    curvature_radius: float

def _init_(self, params: ReqSoftParams):
    self.casing_inner_diameter = params.casing_inner_diameter
    self.tool_outer_diameter = params.tool_outer_diameter
    self.curvature_radius = params.curvature_radius


# 穿心解卡---最大刚性长度计算接口
@router.post("/v3/pierc/pass")
async def pierc_pass(params: ReqSoftParams):
    factor_a: float = params.curvature_radius + params.casing_inner_diameter / 1000 / 2
    factor_b: float = (params.curvature_radius - params.casing_inner_diameter / 1000 / 2 +
                       params.tool_outer_diameter / 1000)
    L_max: float = 2 * math.sqrt(math.pow(factor_a, 2) - math.pow(factor_b, 2))
    return {
        # 不同外径的穿心解卡最大刚性长度
        'L_max': round(L_max, 2),
    }

class PiercMaxOuterParams(BaseModel):
    # 套管内径D
    casing_inner_diameter: float
    # 工具长度L
    tool_length: float
    # 曲率半径R
    curvature_radius: float

def _init_(self, params: PiercMaxOuterParams):
    self.casing_inner_diameter = params.casing_inner_diameter
    self.tool_length = params.tool_length
    self.curvature_radius = params.curvature_radius

# 最大工具外径d
@router.post("/v3/pierc/maxouter")
async def pierc_maxouter(params: PiercMaxOuterParams):
    factor_a: float = params.curvature_radius + params.casing_inner_diameter / 1000 / 2
    factor_b: float = math.pow(params.tool_length, 2) / 4
    D: float = (math.sqrt(
        math.pow(factor_a, 2) - factor_b) - params.curvature_radius + params.casing_inner_diameter / 1000 / 2) * 1000
    D_max: float = round(D, 2)
    return {
        # 不同工具最大外径
        'D_max': D_max,
    }

class PresureParams(BaseModel):
    # 接触长度L
    contact_length: float
    # 电缆直径D
    cable_diameter: float
    # 粘卡处的压差 delta_p
    p_contact: float
    # 摩阻系数 miu
    friction_coefficient: float

def _init_(self, params: PresureParams):
    self.contact_length = params.contact_length
    self.cable_diameter = params.cable_diameter
    self.p_contact = params.p_contact
    self.friction_coefficient = params.friction_coefficient


# 穿心解卡---压差计算接口
@router.post("/v3/pierc/pressure")
async def pierc_pressure(params: PresureParams):
    F_f: float = params.contact_length * params.cable_diameter * params.p_contact * params.friction_coefficient
    return {
            # 摩阻系数、液柱压差、粘卡电缆与泥饼接触长度等各参数不同情况下摩阻力计算
            'F_f':round(F_f, 2),
    }

class CardPointParams(BaseModel):
    # 初始拉力
    initial_force: float
    # 初始伸长系数
    initial_extension_coefficient: float
    # 第一次上提位移
    first_pull_up_displacement: float
    # 第一次上提拉力
    first_pull_up_force: float
    # 第二次上提位移
    second_pull_up_displacement: float
    # 第二次上提拉力
    second_pull_up_force: float
    # 第三次上提位移
    third_pull_up_displacement: float
    # 第三次上提拉力
    third_pull_up_force: float

def _init_(self, params: CardPointParams):
    self.initial_force = params.initial_force
    self.initial_extension_coefficient = params.initial_extension_coefficient
    self.first_pull_up_displacement = params.first_pull_up_displacement
    self.first_pull_up_force = params.first_pull_up_force
    self.second_pull_up_displacement = params.second_pull_up_displacement
    self.second_pull_up_force = params.second_pull_up_force
    self.third_pull_up_displacement = params.third_pull_up_displacement
    self.third_pull_up_force = params.third_pull_up_force
# 穿心解卡---电缆卡点计算接口
@router.post("/v3/pierc/cardpoint")
async def pierc_cardpoint(params: CardPointParams):
    # 平均上提位移delt_l
    delt_l: float = ( params.first_pull_up_displacement + params.second_pull_up_displacement + params.third_pull_up_displacement) / 3
    # 平均悬重增量p
    p: float = ((params.first_pull_up_force - params.initial_force) + (
                params.second_pull_up_force - params.initial_force) +
                (params.third_pull_up_force - params.initial_force)) / 3
    # 电缆伸长系数k
    k: float = params.initial_extension_coefficient / 5
    # 卡点深度L
    L: float = delt_l / k / p
    return {
        # 不同参数下卡点深度计算
        'L': round(L, 2),
    }

class ToolStuckParams(BaseModel):
    # 初始悬重
    initial_tension: float
    # 伸长系数
    extension_coefficient: float
    # 第一次上提位移
    first_pull_up_displacement: float
    # 第一次上提悬重
    first_pull_up_tension: float
    # 第二次上提位移
    second_pull_up_displacement: float
    # 第二次上提悬重
    second_pull_up_tension: float
    # 第三次上提位移
    third_pull_up_displacement: float
    # 第三次上提悬重
    third_pull_up_tension: float
def _init_(self, params: ToolStuckParams):
    self.initial_tension = params.initial_tension
    self.extension_coefficient = params.extension_coefficient
    self.first_pull_up_displacement = params.first_pull_up_displacement
    self.first_pull_up_tension = params.first_pull_up_tension
    self.second_pull_up_displacement = params.second_pull_up_displacement
    self.second_pull_up_tension = params.second_pull_up_tension
    self.third_pull_up_displacement = params.third_pull_up_displacement
    self.third_pull_up_tension = params.third_pull_up_tension
# 穿心解卡---钻具卡点计算接口
@router.post("/v3/pierc/toolstuck")
async def pierc_toolstuck(params: ToolStuckParams):
    # 钻具卡点计算公式
    # 平均上提位移 L
    L: float = ( params.first_pull_up_displacement + params.second_pull_up_displacement + params.third_pull_up_displacement) / 3
    # 平均悬重增量 d
    d: float = ((params.first_pull_up_tension - params.initial_tension) + (
                params.second_pull_up_tension - params.initial_tension) + (
                            params.third_pull_up_tension - params.initial_tension)) / 3
    # 钻柱卡点深度 z
    z: float = L * params.extension_coefficient / d
    return {
        # 不同规格钻具卡点计算
        'z': round(z,2),
        }

class ToolMomentParams(BaseModel):
    # 扭转系数 K
    torsion_coefficient: float
    # 卡点深度 h
    card_depth: float

def _init_(self, params: ToolMomentParams):
    self.torsion_coefficient = params.torsion_coefficient
    self.card_depth = params.card_depth
# 穿心解卡---钻具扭矩计算接口
@router.post("/v3/pierc/toolmoment")
async def pierc_toolmoment(params: ToolMomentParams):
    # 钻具扭矩计算公式
    max_turns:  float = params.torsion_coefficient * params.card_depth
    return {

        'max_turns': round(max_turns, 2),
        }

class StrightWellForceParams(BaseModel):
    # 液体密度
    rho_liud: float
    # 拉力棒的拉力
    F_pullrod_ibf: float
    # 电缆质量
    cable_mass_per_km:float
    # 电缆直径
    cable_diameter_mm:float
    # 井深
    well_depth_m:float
def _init_(self, params: StrightWellForceParams):
    self.rho_liud = params.rho_liud
    self.F_pullrod_ibf = params.F_pullrod_ibf
    self.cable_mass_per_km = params.cable_mass_per_km
    self.cable_diameter_mm = params.cable_diameter_mm
    self.well_depth_m = params.well_depth_m
# 穿心解卡---直井最大安全拉力计算接口
@router.post("/v3/pierc/strightwellforce")
async def pierc_strightwellforce(params: StrightWellForceParams):
    # 电缆的单位密度
    rho_cable: float = (params.cable_mass_per_km / 1000) / (math.pi / 4 * (params.cable_diameter_mm * 0.001) ** 2)
    # 电缆在液体中的单位密度
    rho_o1: float = rho_cable - params.rho_liud
    # 电缆的截面积
    a_cable = math.pi / 4 * (params.cable_diameter_mm * 0.001) ** 2
    # 电缆在液体中的单位质量
    m_cable = rho_o1 * a_cable

    # 拉力棒的拉力转换为牛顿
    f_pullrod_N: float = params.F_pullrod_ibf * 4.45

    # 最大安全拉力
    F_safe_max: float = (params.well_depth_m * m_cable * 9.81 + f_pullrod_N) / 1000
    return {
        'F_safe_max':round(F_safe_max,2)
    }

class InclineWellForceParams(BaseModel):
    # 液体密度
    rho_liud: float
    # 拉力棒的拉力
    F_pullrod_ibf: float
    # 电缆质量
    cable_mass_per_km:float
    # 电缆直径
    cable_diameter_mm:float
    # 井深
    well_depth_m:float
    # 斜度
    incline_degree:float

def _init_(self, params: InclineWellForceParams):
    self.rho_liud = params.rho_liud
    self.F_pullrod_ibf = params.F_pullrod_ibf
    self.cable_mass_per_km = params.cable_mass_per_km
    self.cable_diameter_mm = params.cable_diameter_mm
    self.well_depth_m = params.well_depth_m
    self.incline_degree = params.incline_degree
# 穿心解卡---斜井最大安全拉力计算接口
@router.post("/v3/pierc/inclinewellforce")
async def pierc_inclinewellforce(params: InclineWellForceParams):
    # 电缆的单位密度
    rho_cable: float = (params.cable_mass_per_km / 1000) / (math.pi / 4 * (params.cable_diameter_mm * 0.001) ** 2)
    # 电缆在液体中的单位密度
    rho_o1: float = rho_cable - params.rho_liud
    # 电缆的截面积
    a_cable = math.pi / 4 * (params.cable_diameter_mm * 0.001) ** 2
    # 电缆在液体中的单位质量
    m_cable = rho_o1 * a_cable

    # 拉力棒的拉力转换为牛顿
    f_pullrod_N: float = params.F_pullrod_ibf * 4.45
    # 将倾斜角度从度转换为弧度
    incline_radians = math.radians(params.incline_degree)
    # 最大安全拉力
    F_safe_max: float = ((params.well_depth_m * m_cable * 9.81 + f_pullrod_N) * math.cos(incline_radians)) / 1000
    return {
        'F_safe_max':round(F_safe_max,2)
            }

class CableForceParams(BaseModel):
    # 液体密度
    rho_liud: float
    # 电缆质量
    cable_mass_per_km:float
    # 电缆直径
    cable_diameter_mm:float
    # 仪器质量
    tool_mass: float
    # 仪器直径
    tool_diameter_mm: float
    # 仪器长度
    tool_length_m: float
    # 井深
    well_depth_m: float
def _init_(self, params: CableForceParams):
    self.rho_liud = params.rho_liud
    self.cable_mass_per_km = params.cable_mass_per_km
    self.cable_diameter_mm = params.cable_diameter_mm
    self.tool_mass = params.tool_mass
    self.tool_diameter_mm = params.tool_diameter_mm
    self.tool_length_m = params.tool_length_m
    self.well_depth_m = params.well_depth_m
# 穿心解卡---电缆最大安全拉力计算接口
@router.post("/v3/pierc/cableforce")
async def pierc_cableforce(params: CableForceParams):
    # 电缆的单位密度
    rho_cable = (params.cable_mass_per_km / 1000) / (math.pi / 4 * (params.cable_diameter_mm * 0.001) ** 2)
    rho_o1 = rho_cable - params.rho_liud  # 电缆在液体中的单位密度

    # 电缆的截面积
    A_cable = math.pi / 4 * (params.cable_diameter_mm * 0.001) ** 2

    # 电缆在液体中的单位质量
    m_cable = rho_o1 * A_cable

    # 仪器的单位密度
    rho_tool = (params.tool_mass / params.tool_length_m) / (math.pi / 4 * (params.tool_diameter_mm * 0.001) ** 2)
    rho_o2 = rho_tool - params.rho_liud  # 仪器在液体中的单位密度

    # 仪器的截面积
    A_tool = math.pi / 4 * (params.tool_diameter_mm * 0.001) ** 2

    # 仪器在液体中的单位质量
    m_tool = rho_o2 * A_tool

    # 计算电缆在某深度时的拉力
    F_p = (params.well_depth_m - params.tool_length_m) * m_cable * 9.81 + m_tool * params.tool_length_m * 9.81
    return {
        'F_p':round(F_p / 1000,2)
    }